////////////////////////////////////////////////////////////////////////////////
//                                                                            //
//  Filename:    SpinTestMessage.h                                            //
//  Developer:   Tommy Riddle                                                 //
//  Create date: 05/03/2005                                                   //
//                                                                            //
////////////////////////////////////////////////////////////////////////////////
//                                                                            //
//  Description: Classes to encapsulate protocol message packets used by the  //
//               spin testing infrastructure.                                 //
//                                                                            //
////////////////////////////////////////////////////////////////////////////////
//        Copyright (c) 2005 - Realtime Gaming.  All rights reserved.         //
////////////////////////////////////////////////////////////////////////////////

#if !defined(AFX_SPINTESTMESSAGE_H__E59E6B78_360E_468B_99DB_2B257C48CDFB__INCLUDED_)
#define AFX_SPINTESTMESSAGE_H__E59E6B78_360E_468B_99DB_2B257C48CDFB__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

#pragma warning( push )
// warning C4200: nonstandard extension used : zero-sized array in struct/union
#pragma warning( disable : 4200 )

////////////////////////////////////////////////////////////////////////////////
//
//	CSpinTestMessage
//
//	Generic protocol message for spin testing.  Specific messages will be
//	derived from this class.
//
////////////////////////////////////////////////////////////////////////////////

class CSpinTestMessage
{
public:
	// Enumeration used to identify each specific type of message.
	enum MESSAGE_SUB_CODES
	{
		mscAck,
		mscInitialize,
		mscClientData,
		mscExecuteSpins,
		mscSummaryData,
		mscGetGameModeSummaryData,
		mscGameModeSummaryData,
		mscGetPayoutTypeDetailData,
		mscPayoutTypeDetailData,
		mscGetBonusGameTypeDetailData,
		mscBonusGameTypeDetailData
	};

	// This function must be called by the constructor of the derived class to
	// properly format the common area of the protocol packet.
	void Initialize( MESSAGE_SUB_CODES msc )
	{
		m_byMessageCode = 'T';
		m_byMessageSubCode = (BYTE) msc;
	}

	// This is the slots protocol message code, which is always 'T' for spin
	// test messages.
	BYTE m_byMessageCode;

	// This is the spin test message sub code and should always be set to a
	// value from the MESSAGE_SUB_CODES enumeration.  This variable is used
	// by the code receiving the packet to determine which specific type of spin
	// test message was received.
	BYTE m_byMessageSubCode;
};

////////////////////////////////////////////////////////////////////////////////
//
//	CSpinTestAckMessage
//
//	Specific type of protocol message for spin testing.  This message is a
//	simple acknowledgement sent from the server.  It has only one field that is
//	a boolean success flag.
//
////////////////////////////////////////////////////////////////////////////////

class CSpinTestAckMessage : public CSpinTestMessage
{
public:
	CSpinTestAckMessage()
	{
		// The constructor must call Initialize in the base class to properly
		// format the common area of the protocol packet.
		Initialize( mscAck );

		// Initialize our member variable.
		m_bSuccess = false;
	}

	// This is a boolean flag to indicate success (!= 0) or failure (== 0).
	BYTE m_bSuccess;
};

////////////////////////////////////////////////////////////////////////////////
//
//	CSpinTestInitializeMessage
//
//	Specific type of protocol message for spin testing.  This message is sent by
//	the client to initialize the server.  The client uses this message to
//	specify which slot machine to spin test and to give the server some other
//	details needed to test the machine.
//
////////////////////////////////////////////////////////////////////////////////

class CSpinTestInitializeMessage : public CSpinTestMessage
{
public:
	CSpinTestInitializeMessage()
	{
		// The constructor must call Initialize in the base class to properly
		// format the common area of the protocol packet.
		Initialize( mscInitialize );

		// Initialize our member variables.
		m_byMachineID = 0;
		m_byMachineSubID = 0;
		m_byMaxGameMode = 0;
		m_byMaxPayoutType = 0;
		m_byMaxBonusGameType = 0;
		m_bySubstNoteID = 0;
		m_byNumClientDataSets = 0;
	}

	// The machine ID of the slot machine we want to test.
	BYTE m_byMachineID;

	// The machine sub ID of the slot machine we want to test.
	BYTE m_byMachineSubID;

	// The highest valid game mode.
	BYTE m_byMaxGameMode;

	// The highest valid payout type.
	BYTE m_byMaxPayoutType;

	// The highest valid bonus game type.
	BYTE m_byMaxBonusGameType;

	// The note ID that the slot machine adds to substitute line wins.
	BYTE m_bySubstNoteID;

	// The number of client data sets that will be passed by subsequent
	// CSpinTestClientDataMessage packets.
	BYTE m_byNumClientDataSets;
};

////////////////////////////////////////////////////////////////////////////////
//
//	CSpinTestClientDataMessage
//
//	Specific type of protocol message for spin testing.  This message is sent by
//	the client to pass in the client data that the server should use if the game
//  can not complete.  This message contains all of the information necessary
//	for one call to the SlotGuts::processClientData function.  It may be sent
//	as many times as needed in order to provide enough data sets to complete a
//	game.  Once the last data set has ben used, the server will wrap back around
//	to the first data set.
//
////////////////////////////////////////////////////////////////////////////////

class CSpinTestClientDataMessage : public CSpinTestMessage
{
public:
	CSpinTestClientDataMessage()
	{
		// The constructor must call Initialize in the base class to properly
		// format the common area of the protocol packet.
		Initialize( mscClientData );

		// Initialize our member variables.
		m_byBonusGameType = 0;
		m_byDataCount = 0;
	}

	// The bonus game type to be passed to SlotGuts::processClientData.
	BYTE m_byBonusGameType;

	// The number of items in the data array.
	BYTE m_byDataCount;

	// The array of client data values.
	DWORD m_adwData[];
};

////////////////////////////////////////////////////////////////////////////////
//
//	CSpinTestExecuteSpinsMessage
//
//	Specific type of protocol message for spin testing.  This message is sent by
//	the client to request that the server execute a batch of spins.  The packet
//	contains the parameters needed to create the batch of spins.
//
////////////////////////////////////////////////////////////////////////////////

class CSpinTestExecuteSpinsMessage : public CSpinTestMessage
{
public:
	CSpinTestExecuteSpinsMessage()
	{
		// The constructor must call Initialize in the base class to properly
		// format the common area of the protocol packet.
		Initialize( mscExecuteSpins );

		// Initialize our member variables.
		m_nNumSpins = 0;
		m_nNumLines = 0;
		m_nBetPerLine = 0;
	}

	// The mininum number of spins to execute in this batch.  Note:  If the
	// machine is in a feature after that many spins it will continue spinning
	// until the feature exits.
	DWORD m_nNumSpins;

	// The number of lines to bet on each spin.
	DWORD m_nNumLines;

	// The amount to bet on each line in base currency units (pennies for USD).
	DWORD m_nBetPerLine;
};

////////////////////////////////////////////////////////////////////////////////
//
//	CSpinTestSummaryDataMessage
//
//	Specific type of protocol message for spin testing.  This message is sent by
//	the server once it has completed a batch of spins.  It contains summary
//	information that was collected during the spins.
//
////////////////////////////////////////////////////////////////////////////////

class CSpinTestSummaryDataMessage : public CSpinTestMessage
{
public:
	CSpinTestSummaryDataMessage()
	{
		// The constructor must call Initialize in the base class to properly
		// format the common area of the protocol packet.
		Initialize( mscSummaryData );

		// Initialize our member variables.
		m_nTotalBet = 0;
		m_nTotalPayout = 0;
		m_dSumPayoutsSquared = 0;
		m_nTotalProgressivePayout = 0;
		m_nTotalLinesPlayed = 0;
		m_nPaidLinesPlayed = 0;
		m_nFreeLinesPlayed = 0;
	}

	// The total amount of money bet during the batch of spins, in base currency
	// units (pennies for USD).
	DWORD m_nTotalBet;

	// The total payout during the batch of spins in base currency units,
	// including the payout from every game mode and from progressives.
	DWORD m_nTotalPayout;

	// The sum of the payouts squared for each paid game.  Used to calculate the true
	// standard deviation of the sample spins.
	double m_dSumPayoutsSquared;

	// The total payout from progressives during the batch of spins, in base
	// currency units.
	DWORD m_nTotalProgressivePayout;

	// The total number of lines played during the batch of spins, including
	// both paid lines and free lines.
	DWORD m_nTotalLinesPlayed;

	// The total number of paid lines played during the batch of spins.
	DWORD m_nPaidLinesPlayed;

	// The total number of free lines played during the batch of spins.
	DWORD m_nFreeLinesPlayed;
};

////////////////////////////////////////////////////////////////////////////////
//
//	CSpinTestGetGameModeSummaryDataMessage
//
//	Specific type of protocol message for spin testing.  This message is sent by
//	the client to get certain specific details about the batch of spins just
//	completed.  The client sends this message once for each game mode to get the
//  summary data for that game mode.
//
////////////////////////////////////////////////////////////////////////////////

class CSpinTestGetGameModeSummaryDataMessage : public CSpinTestMessage
{
public:
	CSpinTestGetGameModeSummaryDataMessage()
	{
		// The constructor must call Initialize in the base class to properly
		// format the common area of the protocol packet.
		Initialize( mscGetGameModeSummaryData );

		// Initialize our member variables.
		m_byGameMode = 0;
	}

	// The game mode of the summary data requested.
	BYTE m_byGameMode;
};

////////////////////////////////////////////////////////////////////////////////
//
//	CSpinTestGameModeSummaryDataMessage
//
//	Specific type of protocol message for spin testing.  This message is sent by
//	the server upon request to provide certain specific details about the batch
//	of spins just completed.  It contains information about the requested game
//	mode.
//
////////////////////////////////////////////////////////////////////////////////

class CSpinTestGameModeSummaryDataMessage : public CSpinTestMessage
{
public:
	CSpinTestGameModeSummaryDataMessage()
	{
		// The constructor must call Initialize in the base class to properly
		// format the common area of the protocol packet.
		Initialize( mscGameModeSummaryData );

		// Initialize our member variables.
		m_nTotalPayout = 0;
		m_nNumTriggers = 0;
	}

	// The total payout for this game mode.
	DWORD m_nTotalPayout;

	// The number of times this game mode was triggered.
	DWORD m_nNumTriggers;
};

////////////////////////////////////////////////////////////////////////////////
//
//	CSpinTestGetPayoutTypeDetailDataMessage
//
//	Specific type of protocol message for spin testing.  This message is sent by
//	the client to get certain specific details about the batch of spins just
//	completed.  The client sends this message once for each game mode and payout
//	type to get the details for that payout type.
//
////////////////////////////////////////////////////////////////////////////////

class CSpinTestGetPayoutTypeDetailDataMessage : public CSpinTestMessage
{
public:
	CSpinTestGetPayoutTypeDetailDataMessage()
	{
		// The constructor must call Initialize in the base class to properly
		// format the common area of the protocol packet.
		Initialize( mscGetPayoutTypeDetailData );

		// Initialize our member variables.
		m_byGameMode = 0;
		m_byPayoutType = 0;
	}

	// The game mode of the detail data requested.
	BYTE m_byGameMode;

	// The payout type of the detail data requested.
	BYTE m_byPayoutType;
};

////////////////////////////////////////////////////////////////////////////////
//
//	CSpinTestPayoutTypeDetailDataMessage
//
//	Specific type of protocol message for spin testing.  This message is sent by
//	the server upon request to provide certain specific details about the batch
//	of spins just completed.  It contains information about the requested payout
//	type and game mode.
//
////////////////////////////////////////////////////////////////////////////////

class CSpinTestPayoutTypeDetailDataMessage : public CSpinTestMessage
{
public:
	CSpinTestPayoutTypeDetailDataMessage()
	{
		// The constructor must call Initialize in the base class to properly
		// format the common area of the protocol packet.
		Initialize( mscPayoutTypeDetailData );

		// Initialize our member variables.
		m_nHitsNoSubst = 0;
		m_nPayoutNoSubst = 0;
		m_nHitsWithSubst = 0;
		m_nPayoutWithSubst = 0;
	}

	// The number of times the payout type hit without a substitute in this game mode.
	DWORD m_nHitsNoSubst;

	// The total payout without substitutes for the payout type in this game mode.
	DWORD m_nPayoutNoSubst;

	// The number of times the payout type hit with a substitute in this game mode.
	DWORD m_nHitsWithSubst;

	// The total payout with substitutes for the payout type in this game mode.
	DWORD m_nPayoutWithSubst;
};

////////////////////////////////////////////////////////////////////////////////
//
//	CSpinTestGetBonusGameTypeDetailDataMessage
//
//	Specific type of protocol message for spin testing.  This message is sent by
//	the client to get certain specific details about the batch of spins just
//	completed.  The client sends this message once for each bonus game type to
//	get the details for that bonus game type.
//
////////////////////////////////////////////////////////////////////////////////

class CSpinTestGetBonusGameTypeDetailDataMessage : public CSpinTestMessage
{
public:
	CSpinTestGetBonusGameTypeDetailDataMessage()
	{
		// The constructor must call Initialize in the base class to properly
		// format the common area of the protocol packet.
		Initialize( mscGetBonusGameTypeDetailData );

		// Initialize our member variables.
		m_byBonusGameType = 0;
	}

	// The bonus game type of the detail data requested.
	BYTE m_byBonusGameType;
};

////////////////////////////////////////////////////////////////////////////////
//
//	CSpinTestBonusGameTypeDetailDataMessage
//
//	Specific type of protocol message for spin testing.  This message is sent by
//	the server upon request to provide certain specific details about the batch
//	of spins just completed.  It contains information about the requested bonus
//	game type.
//
////////////////////////////////////////////////////////////////////////////////

class CSpinTestBonusGameTypeDetailDataMessage : public CSpinTestMessage
{
public:
	CSpinTestBonusGameTypeDetailDataMessage()
	{
		// The constructor must call Initialize in the base class to properly
		// format the common area of the protocol packet.
		Initialize( mscBonusGameTypeDetailData );

		// Initialize our member variables.
		m_nHits = 0;
		m_nTotalPayout = 0;
	}

	// The number of times the bonus game type hit in this game mode.
	DWORD m_nHits;

	// The total payout for the bonus game type in this game mode.
	DWORD m_nTotalPayout;
};

#pragma warning( pop )

#endif // !defined(AFX_SPINTESTMESSAGE_H__E59E6B78_360E_468B_99DB_2B257C48CDFB__INCLUDED_)
